package com.rkjoeson.player;

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.pili.pldroid.player.PLOnBufferingUpdateListener;
import com.pili.pldroid.player.PLOnCompletionListener;
import com.pili.pldroid.player.PLOnErrorListener;
import com.pili.pldroid.player.PLOnInfoListener;
import com.pili.pldroid.player.PLOnPreparedListener;
import com.pili.pldroid.player.PLOnSeekCompleteListener;
import com.pili.pldroid.player.PLOnVideoSizeChangedListener;
import com.pili.pldroid.player.widget.PLVideoView;
import com.rkjoeson.player.constants.QiniuPlayerEventConstants;

import java.util.Map;

public class RNTQiniuPlayerViewManager extends SimpleViewManager<PLVideoView> implements LifecycleEventListener,
    PLOnVideoSizeChangedListener,
    PLOnPreparedListener,
    PLOnInfoListener,
    PLOnBufferingUpdateListener,
    PLOnCompletionListener,
    PLOnSeekCompleteListener,
    PLOnErrorListener
{
    private final String REACT_CLASS = "RNTShortVideo";

    private ThemedReactContext context;
    private RCTEventEmitter mEventEmitter;
    private PLVideoView plVideoView;
    private Boolean isPlay = false;

    @Override
    public void onHostResume() {
        if (this.isPlay) {
            if (!plVideoView.isPlaying()) {
                plVideoView.start();
            }
        } else {
            plVideoView.pause();
        }
    }

    @Override
    public void onHostPause() {
        plVideoView.pause();
    }

    @Override
    public void onHostDestroy() {
        plVideoView.stopPlayback();
        context.removeLifecycleEventListener(this);
    }

    @NonNull
    @Override
    public String getName() {
        return REACT_CLASS;
    }

    @Override
    @Nullable
    public Map getExportedCustomDirectEventTypeConstants() {
        MapBuilder.Builder<String, Map<String, String>> builder = MapBuilder.builder();
        for (String event : QiniuPlayerEventConstants.EVENT_LIST) {
            builder.put(event, MapBuilder.of("registrationName", event));
        }
        return builder.build();
    }

    @NonNull
    @Override
    protected PLVideoView createViewInstance(@NonNull ThemedReactContext reactContext) {
        context = reactContext;
        // 注册生命周期
        context.addLifecycleEventListener(this);
        // 获取对应的json事件对象
        mEventEmitter = context.getJSModule(RCTEventEmitter.class);
        // 初始化对应的推流视图
        initPLVideoView();
        return plVideoView;
    }

    @Override
    public void onDropViewInstance(@NonNull PLVideoView view) {
        super.onDropViewInstance(view);
        if (view.canPause()) {
            view.pause();
        }
        view.stopPlayback();
    }

    /**
     * 初始化配置
     */
    private void initPLVideoView() {
        plVideoView = new PLVideoView(context);
        // 保持屏幕亮
        plVideoView.setKeepScreenOn(true);

        // 注册事件
        plVideoView.setOnPreparedListener(this);
        plVideoView.setOnInfoListener(this);
        plVideoView.setOnVideoSizeChangedListener(this);
        plVideoView.setOnBufferingUpdateListener(this);
        plVideoView.setOnCompletionListener(this);
        plVideoView.setOnSeekCompleteListener(this);
        plVideoView.setOnErrorListener(this);
    }

    /**
     * 获取视图id
     *
     * @return int
     */
    private int getId() {
        return plVideoView.getId();
    }

    /**
     * 播放的流大小变化
     *
     * @param width  int
     * @param height int
     */
    @Override
    public void onVideoSizeChanged(int width, int height) {
        Log.d("播放器", "onVideoSizeChanged: " + width + "," + height);
    }

    /**
     * 准备事件
     *
     * @param i int
     */
    @Override
    public void onPrepared(int i) {
        Log.d("播放器", "onPrepared ! ");
        mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_LOADING, Arguments.createMap());
    }

    /**
     * 对应的事件流信息回调
     *
     * @param i  int
     * @param i1 int
     */
    @Override
    public void onInfo(int i, int i1) {
        switch (i) {
            case MEDIA_INFO_VIDEO_RENDERING_START:
                mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_PLAYING, Arguments.createMap());
                break;
            case MEDIA_INFO_BUFFERING_START:
                mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_LOADING, Arguments.createMap());
                break;
            case MEDIA_INFO_BUFFERING_END:
                mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_PLAYING, Arguments.createMap());
                break;
        }
    }

    /**
     * buffer更新
     *
     * @param i int
     */
    @Override
    public void onBufferingUpdate(int i) {
        Log.d("播放器", "onBufferingUpdate: " + i);
    }

    /**
     * 播放完成
     */
    @Override
    public void onCompletion() {
        Log.d("播放器", "Play Completed !");
        mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_SHUTDOWN, Arguments.createMap());
    }

    /**
     * 拖拽
     */
    @Override
    public void onSeekComplete() {
        Log.d("播放器", "onSeekComplete !");
    }

    /**
     * 发生错误
     *
     * @param i int
     * @return boolean
     */
    @Override
    public boolean onError(int i) {
        Log.e("播放器", "Error happened, errorCode = " + i);
        WritableMap event = Arguments.createMap();
        event.putInt("error", i);
        mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_PLAYER_ERROR, Arguments.createMap());
        return true;
    }

    /**
     * 是否开始
     *
     * @param plVideoView PLVideoView
     * @param started     boolean
     */
    @ReactProp(name = "isPlay")
    public void setIsPlay(PLVideoView plVideoView, boolean started) {
        this.isPlay = started;
        if (started) {
            plVideoView.start();
        } else {
            plVideoView.pause();
            mEventEmitter.receiveEvent(getId(), QiniuPlayerEventConstants.ON_PAUSED, null);
        }
    }

    /**
     * 比例配置
     * ASPECT_RATIO_ORIGIN = 0;
     * ASPECT_RATIO_FIT_PARENT = 1
     * ASPECT_RATIO_PAVED_PARENT = 2
     * ASPECT_RATIO_16_9 = 3
     * ASPECT_RATIO_4_3 = 4
     *
     * @param plVideoView PLVideoView
     * @param aspectRatio int
     */
    @ReactProp(name = "aspectRatio")
    public void setAspectRatio(PLVideoView plVideoView, int aspectRatio) {
        plVideoView.setDisplayAspectRatio(aspectRatio);
    }

    /**
     * 配置封面
     *
     * @param plVideoView PLVideoView
     * @param source      String
     */
    @ReactProp(name = "coverImage")
    public void setCoverImageSource(PLVideoView plVideoView, @NonNull String source) {

    }
}
